/*
 * @Author: 15663569761 1697354625@qq.com
 * @Date: 2023-05-26 20:12:45
 * @LastEditors: 15663569761 1697354625@qq.com
 * @LastEditTime: 2023-05-26 20:19:56
 * @FilePath: /lesson43/tcpServer/daemon.hpp
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#pragma once

#include<unistd.h>
#include<signal.h>
#include<cstdlib>
#include<cassert>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>

#define DEV "/dev/null"
void daemonSelf(const char* currPath = nullptr)
{
    //1. 让调用进程忽略掉异常的信号退出的信号关掉
    signal(SIGPIPE, SIG_IGN); //把xshell退出的信号忽略掉
    //2.如何让自己不是组长从而调用sid
    if(fork() > 0) exit(0);
    //只能是子进程 -- 守护进程，精灵进程，本质就是孤儿进程的一种
    pid_t n = setsid();
    assert(n != -1);
    
    //3. 守护进程是脱离终端的，不需要和Xshell打交道，也不需要和命令行打交道，因此需要关闭或者重定向以前进程默认打开的文件
    //ps: /dev/null -> 黑洞，相当于垃圾桶，专门用来什么都不做，写入的信息会自动丢弃
    int fd = open(DEV, O_RDWR);
    if(fd >= 0)
    {
        dup2(fd, 0);
        dup2(fd, 1);
        dup2(fd, 2);

        close(fd);
    }
    else
    {
        close(0);
        close(1);
        close(2);
    }
    //4. 可选：进程执行路径发生更改
    if(currPath)
        chdir(currPath);
}